/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <引擎数据类型.h>

#include <core/属性.h>
#include <core/结构数据.h>
#include <线性代数/几何计算.h>

#include "节点/节点.h"




struct S_JIT_函数指针名称 {
	//static std::vector<std::string> g函数指针类型定义名称;
	static std::vector<std::string> g函数指针名称;
	static std::vector<std::string> g返回类型;
	static std::vector<std::string> g参数类型;
};

std::string f_代码构建_函数指针();
std::vector<E_JIT_FunParam>& f_代码构建_取参数函数指针();
std::string f_代码构建_JIT函数指针初始化();
void f_代码构建_添加JIT初始化函数指针(std::string 定义名称, std::string 返回类型, std::string 参数类型, void* fp);



#define f_JIT_Fun_vec3_alloc f_JIT_Fun_vec3_alloc
#define f_JIT_Fun_vec3_free f_JIT_Fun_vec3_free
#define f_JIT_Fun_vec3_resize f_JIT_Fun_vec3_resize
#define f_JIT_Fun_vec3_插入 f_JIT_Fun_vec3_insert
#define f_JIT_Fun_vec3_size f_JIT_Fun_vec3_size

#define f_JIT_Fun_vec3s_add_vec3 f_JIT_Fun_vec3s_add_vec3
#define f_JIT_Fun_vec3s_add_vec3s f_JIT_Fun_vec3s_add_vec3s




std::string f_代码构建_预定义类型();

std::string f_代码构建_创建vec3数组(std::string name);
std::string f_代码构建_取vec3数组数量(std::string& 变量名称, std::string var);
std::string f_代码构建_vec3数组分配(std::string name, std::string num);
std::string f_代码构建_释放vec3数组(const std::string& name);
std::string f_代码构建_新建变量忽略负数(const std::string& 变量, std::string& 新变量名称);

std::string f_代码构建_多边形边数组数量(std::string& 变量名称, const std::string& 多边形代码);

std::string f_代码构建_创建vec3_Array(std::string& 新变量名称, const std::string& 数量);
std::string f_代码构建_创建Array(E_值类型 类型, const std::string& 数量);
std::string f_代码构建_销毁数组(std::string 新变量名称);
std::string f_代码构建_Array数组数量(std::string var);
std::string f_代码构建_Array元素大小(std::string var);

Inline std::string f_代码构建_创建数组(E_值类型 类型, const uint32 数量) {
	return f_代码构建_创建Array(类型, f_整数值转字符串(数量));
}



Inline bool f_代码构建_是否为数组(E_值类型 type) {
	switch (type) {
		case E_值类型::e_Type_Mesh:
		case E_值类型::e_Type_Mesh_1D:
		case E_值类型::e_Type_多边形:
		case E_值类型::e_Type_多边形_1D:

		case E_值类型::e_Type_多边形边:
		case E_值类型::e_Type_多边形边1D:

		case E_值类型::e_Type_多边形元素:
		case E_值类型::e_Type_多边形元素1D:
		case E_值类型::e_Type_多边形面:
		case E_值类型::e_Type_Bool_1D:
		case E_值类型::e_Type_Vec2_1D:
		case E_值类型::e_Type_Vec3_1D:
		case E_值类型::e_Type_Vec4_1D:
		case E_值类型::e_Type_Mat4X4_1D:
		
		case E_值类型::e_Type_I8_1D:
		case E_值类型::e_Type_I32_1D:
		case E_值类型::e_Type_UI32_1D:
		case E_值类型::e_Type_UI32_2D:
		case E_值类型::e_Type_F32_1D:
		case E_值类型::e_Type_iVec2_1D:
		case E_值类型::e_Type_iVec3_1D:

		case E_值类型::e_Type_iVec3_2D:
		case E_值类型::e_Type_Vec3_2D:
		//case E_值类型::e_Type_iVec4_1D:
		case E_值类型::e_Type_材质1D:
		case E_值类型::e_Type_纹理1D:
		case E_值类型::e_Type_Array:
			return true;
	}
	return false;
}



Inline E_值类型 f_代码构建_数组元素取数组类型(E_值类型 type) {
	switch (type) {
		case E_值类型::e_Type_I8: return E_值类型::e_Type_I8_1D;
		case E_值类型::e_Type_Mesh: return E_值类型::e_Type_Mesh_1D;
		case E_值类型::e_Type_多边形面: return E_值类型::e_Type_多边形元素;
		case E_值类型::e_Type_多边形元素: return E_值类型::e_Type_多边形元素1D;
		//case E_值类型::e_Type_面: return E_值类型::e_Type_多边形面:
		case E_值类型::e_Type_Bool: return E_值类型::e_Type_Bool_1D;
		case E_值类型::e_Type_Vec2: return E_值类型::e_Type_Vec2_1D;
		case E_值类型::e_Type_Vec3: return  E_值类型::e_Type_Vec3_1D;
		case E_值类型::e_Type_Vec4: return  E_值类型::e_Type_Vec4_1D;
		case E_值类型::e_Type_Mat4X4: return  E_值类型::e_Type_Mat4X4_1D;
		
		case E_值类型::e_Type_I32: return  E_值类型::e_Type_I32_1D;
		case E_值类型::e_Type_I32_1D: return  E_值类型::e_Type_I32_2D;

		case E_值类型::e_Type_UI32: return  E_值类型::e_Type_UI32_1D;
		case E_值类型::e_Type_UI32_1D: return  E_值类型::e_Type_UI32_2D;

		case E_值类型::e_Type_F32: return  E_值类型::e_Type_F32_1D;
		case E_值类型::e_Type_iVec2: return  E_值类型::e_Type_iVec2_1D;

		case E_值类型::e_Type_iVec3: return  E_值类型::e_Type_iVec3_1D;
		case E_值类型::e_Type_iVec3_1D: return  E_值类型::e_Type_iVec3_2D;

		case E_值类型::e_Type_Vec3_1D: return  E_值类型::e_Type_Vec3_2D;
		//case E_值类型::e_Type_iVec4_1D:
		//case E_值类型::e_Type_Array:
		//	return E_值类型::e_Type_Array;
		case E_值类型::e_Type_多边形边: return E_值类型::e_Type_多边形边1D;
		case E_值类型::e_Type_Object: return E_值类型::e_Type_Object_1D;
		case E_值类型::e_Type_材质: return E_值类型::e_Type_材质1D;
	}
	return E_值类型::e_Type_Array;
}


Inline E_值类型 f_代码构建_数组元素类型(E_值类型 type) {
	switch (type) {
		case E_值类型::e_Type_I8_1D: return E_值类型::e_Type_I8;
		case E_值类型::e_Type_F32_1D: return E_值类型::e_Type_F32;
		case E_值类型::e_Type_I32_1D: return E_值类型::e_Type_I32;
		case E_值类型::e_Type_Vec2_1D: return E_值类型::e_Type_Vec2;

		case E_值类型::e_Type_Vec3_1D: return E_值类型::e_Type_Vec3;
		case E_值类型::e_Type_Vec3_2D: return E_值类型::e_Type_Vec3_1D;

		case E_值类型::e_Type_Vec4_1D: return E_值类型::e_Type_Vec4;
		case E_值类型::e_Type_iVec2_1D: return E_值类型::e_Type_iVec2;


		case E_值类型::e_Type_UI32_1D: return E_值类型::e_Type_UI32;
		case E_值类型::e_Type_UI32_2D: return E_值类型::e_Type_UI32_1D;

		case E_值类型::e_Type_iVec3_1D: return E_值类型::e_Type_iVec3;
		case E_值类型::e_Type_iVec3_2D: return E_值类型::e_Type_iVec3_1D;

		case E_值类型::e_Type_uVec2_1D: return E_值类型::e_Type_uVec2;
		case E_值类型::e_Type_多边形边1D: return E_值类型::e_Type_多边形边;

		case E_值类型::e_Type_材质1D: return E_值类型::e_Type_材质;

		//case E_值类型::e_Type_Array:
		//	break;
		default:
			break;
	}
	return E_值类型::e_插座Type_引用数据;
}


Inline bool f_代码构建_矢量类型(E_值类型 type) {
	switch (type) {
		case E_值类型::e_Type_Vec2:
		case E_值类型::e_Type_Vec3:
		case E_值类型::e_Type_Vec4:
		case E_值类型::e_Type_iVec2:
		case E_值类型::e_Type_iVec3:
		case E_值类型::e_Type_uVec2:

		case E_值类型::e_Type_Vec2_1D:
		case E_值类型::e_Type_Vec3_1D:
		case E_值类型::e_Type_Vec3_2D:
		case E_值类型::e_Type_Vec4_1D:
		case E_值类型::e_Type_iVec2_1D:
		case E_值类型::e_Type_iVec3_1D:
		case E_值类型::e_Type_iVec3_2D:
		case E_值类型::e_Type_uVec2_1D:
			return true;
	}
	return false;
}




bool f_代码构建_是否为单值浮点(E_值类型 type);
bool f_代码构建_是否为单值数组浮点(E_值类型 type);

bool f_代码构建_是否为矢量浮点(E_值类型 type);
bool f_代码构建_是否为矢量数组浮点(E_值类型 type);
E_值类型 f_代码构建_多维数组元素(E_值类型 type);
E_值类型 f_代码构建_多维数组(E_值类型 type);


std::string f_代码构建_i32GPU变量(S_Props& 属性);

Inline std::string f_代码构建_ID变量名称(C_节点基类* node) {
	return node->f_getName() + "_LoopID";
}


void f_代码构建_内联函数声明定义(const std::string keyName, const std::string& 函数声明, const std::string& 函数代码);
bool f_代码构建_内联函数保存到文件();


std::string f_代码构建_插座信息调试(C_插座基类* socket);
void f_代码构建_清除代码缓存();


